using System;
using DNT.RavenQA.Core.Extensions;

namespace DNT.RavenQA.Core.Models
{
    public abstract class Contribute : Entity<Int32>
    {
        public String Body { get; protected set; }

        public DateTimeOffset PostedOn { get; protected set; }

        public String VotesId { get; protected set; }

        public DenormalizedReference<User> User { get; protected set; }

        private void EnsureHasVotes(ContributeVotes votes)
        {
            if (VotesId.IsNotNull() && votes.Id != VotesId)
                throw new InvalidReferenceException();

            if (VotesId.IsNull())
                VotesId = votes.Id;
        }

        private void Vote(Func<ContributeVotes> func, User user, Func<User, ContributeVotes.Vote> voteFunc)
        {
            func.EnsureIsNotNull("func");
            user.EnsureIsNotNull("user");
            voteFunc.EnsureIsNotNull("voteFunc");

            var votes = func();
            EnsureHasVotes(votes);
            votes.New(user, voteFunc);
        }

        public void VoteUp(Func<ContributeVotes> func, User user)
        {
            Vote(func, user, ContributeVotes.Vote.NewUp);
        }

        public void VoteDown(Func<ContributeVotes> func, User user)
        {
            Vote(func, user, ContributeVotes.Vote.NewDown);
        }
    }
}